package cn.magictodo.weblog.admin.schedule;

import cn.magictodo.weblog.common.domain.dos.StatisticsArticlePVDO;
import cn.magictodo.weblog.common.domain.mapper.StatisticsArticlePVMapper;
import com.github.jaemon.dinger.DingerSender;
import com.github.jaemon.dinger.core.entity.DingerRequest;
import com.github.jaemon.dinger.core.entity.enums.MessageSubType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

import static cn.magictodo.weblog.common.enums.RedisPrefixEnum.REDIS_ARTICLE_PV;

/**
 * @author liu
 * @since 2023-11-27 13:33
 */
@Component
@Slf4j
public class InitPVRecordScheduledTask {

    @Autowired
    private StatisticsArticlePVMapper articlePVMapper;

    @Autowired
    private DingerSender dingerSender;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;



    @Scheduled(cron = "0 55 23 * * ?") // 每天晚间 23 点执行
    @Async("threadPoolTaskExecutor")
    public void execute() {

        // 定时任务执行的业务逻辑
        log.info("==> 开始执行初始化明日 PV 访问量记录定时任务");

        // 当日日期
        LocalDate currDate = LocalDate.now();
        StatisticsArticlePVDO statisticsArticlePVDO = articlePVMapper.selectRecordsByDate(currDate);

        if (statisticsArticlePVDO == null) {
//      如果今日访问量为空，说明昨天没初始化，需要重新初始化一下pv
            statisticsArticlePVDO = StatisticsArticlePVDO.builder()
                    .pvDate(currDate) // 今天的文章 pv 访问量
                    .pvCount(0L) // 默认阅读量为 0
                    .createTime(LocalDateTime.now())
                    .updateTime(LocalDateTime.now())
                    .build();
            articlePVMapper.insert(statisticsArticlePVDO);
        }

        log.info("==> 当日日期：{}", currDate);

//            通过当日日期获取当日PV
            Object valueFromRedis = redisTemplate.opsForValue().get(REDIS_ARTICLE_PV.getPrefix() + currDate);
            Long pV = 0L;
            // 判断并转换为Long类型
        if (valueFromRedis != null){
            if (valueFromRedis instanceof Integer) {
                pV = ((Integer) valueFromRedis).longValue();
            } else if (valueFromRedis instanceof Long) {
                pV = (Long) valueFromRedis;
            } else if (valueFromRedis instanceof String) {
                try {
                    pV = Long.parseLong((String) valueFromRedis);
                } catch (NumberFormatException e) {
                    // 处理转换失败的情况
                    System.out.println("The string value from Redis cannot be parsed as a Long.");
                }
            } else {
                // 处理未知类型的情况
                System.out.println("The value retrieved from Redis is of an unsupported type for conversion to Long.");
            }
            articlePVMapper.increasePVCount(currDate, pV);

//            清除当日pv
            redisTemplate.delete(REDIS_ARTICLE_PV.getPrefix() + currDate);
        }

        dingerSender.send(MessageSubType.MARKDOWN,
                DingerRequest.request("今日文章访问量为"+pV,"文章访问量统计"));

        // 明日
        LocalDate tomorrowDate = currDate.plusDays(1);

        // 组装插入的记录
        StatisticsArticlePVDO articlePVDO = StatisticsArticlePVDO.builder()
                .pvDate(tomorrowDate) // 明日的文章 pv 访问量
                .pvCount(0L) // 默认阅读量为 0
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .build();

        int insert = articlePVMapper.insert(articlePVDO);
        if (insert > 0) {
            redisTemplate.opsForValue().set(REDIS_ARTICLE_PV.getPrefix() + tomorrowDate,0L,2, TimeUnit.DAYS);
        } else {
            log.error("==> 初始化明日 PV 访问量记录失败");
        }

        log.info("==> 结束执行初始化明日 PV 访问量记录定时任务");
    }
}
